package cn.iocoder.yudao.module.book.service.app;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.PASSWORD_DOES_NOT_EXIST;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.book.controller.app.vo.*;
import cn.iocoder.yudao.module.book.dal.dataobject.*;
import cn.iocoder.yudao.module.book.dal.dataobject.book.BookDO;
import cn.iocoder.yudao.module.book.dal.mysql.*;
import cn.iocoder.yudao.module.book.service.admin.book.BookService;
import jakarta.annotation.Resource;

@Service
public class BookClassManagementServiceImpl implements BookClassManagementService {

    @Resource
    private BookClassManagementMapper bookClassManagementMapper;
    @Resource
    private BookClassManagementMemberMapper bookClassManagementMemberMapper;
    @Resource
    private BookSchoolAssignmentMapper bookSchoolAssignmentMapper;
    @Resource
    private BookClassAndSchoolMapper bookClassAndSchoolMapper;
    @Resource
    private BookCheckInRecordMapper bookCheckInRecordMapper;
    @Resource
    private BookService bookService;

    public static String generate10UniqueDigitsAsString() {
        List<Character> pool = new ArrayList<>();
        for (char c = '0'; c <= '9'; c++) {
            pool.add(c);
        }
        Collections.shuffle(pool); // 打乱顺序
        StringBuilder sb = new StringBuilder();
        for (char c : pool) {
            sb.append(c);
        }
        return sb.toString(); // 10 位不重复，如 3806174952
    }

    @Override
    public Long createBookClassManagement(BookClassManagementReqVO createReqVO) {
        BookClassManagementDO bookClassManagementDO = BeanUtils.toBean(createReqVO, BookClassManagementDO.class);
        bookClassManagementDO
                .setClassManagementTeacher(StringUtils.isNoneBlank(createReqVO.getClassManagementTeacher()) ? createReqVO.getClassManagementTeacher() : getLoginUserNickname());
        bookClassManagementDO.setClassManagementPassword(generate10UniqueDigitsAsString());
        bookClassManagementMapper.insert(bookClassManagementDO);
        BookClassManagementMemberDO bookClassManagementMemberDO = new BookClassManagementMemberDO();
        bookClassManagementMemberDO.setClassManagementId(bookClassManagementDO.getId());
        bookClassManagementMemberDO.setMemberId(getLoginUserId());
        bookClassManagementMemberDO.setMemberName(createReqVO.getClassManagementTeacher());
        bookClassManagementMemberMapper.insert(bookClassManagementMemberDO);
        return bookClassManagementDO.getId();
    }

    @Override
    public Long JoinBookClassManagement(BookClassManagementMemberReqVO bookClassManagementMemberReqVO) {
        BookClassManagementDO bookClassManagementDO = bookClassManagementMapper
                .selectOne(new QueryWrapperX<BookClassManagementDO>().eq("class_management_password", bookClassManagementMemberReqVO.getClassManagementPassword()));
        if (bookClassManagementDO == null) {
            throw exception(PASSWORD_DOES_NOT_EXIST);
        }
        BookClassManagementMemberDO bookClassManagementMemberDO = new BookClassManagementMemberDO();
        bookClassManagementMemberDO.setClassManagementId(bookClassManagementDO.getId());
        bookClassManagementMemberDO.setMemberId(getLoginUserId());
        bookClassManagementMemberDO.setMemberName(bookClassManagementMemberReqVO.getMemberName());
        bookClassManagementMemberMapper.insert(bookClassManagementMemberDO);
        return bookClassManagementMemberDO.getId();
    }

    @Override
    public BookClassManagementRespVO getBookClassManagementById(String id) {
        // 根据当前用户ID查询班级信息，如果存在则返回班级信息，不存在则返回null
        BookClassManagementDO bookClassManagementDO = bookClassManagementMapper.selectJoinOne(BookClassManagementDO.class, new MPJLambdaWrapper<BookClassManagementDO>()
                .leftJoin(BookClassManagementMemberDO.class, BookClassManagementMemberDO::getClassManagementId, BookClassManagementDO::getId)
                .eq(BookClassManagementMemberDO::getMemberId, getLoginUserId()).eq(BookClassManagementDO::getId, id));
        if (bookClassManagementDO == null) {
            return null;
        }
        BookClassManagementRespVO bookClassManagementRespVO = BeanUtils.toBean(bookClassManagementDO, BookClassManagementRespVO.class);
        // 存在则查询作业、打卡（1/1）、成员信息
        // 查询该班级下所有成员
        List<BookSchoolAssignmentListVO> bookSchoolAssignmentListVOList = bookClassManagementMemberMapper.selectListByClassManagementId(bookClassManagementRespVO.getId());
        // 查询该班级作业列表
        List<BookSchoolAssignmentDO> bookSchoolAssignmentDOList =
                bookSchoolAssignmentMapper.selectList(new QueryWrapperX<BookSchoolAssignmentDO>().eq("class_management_id", bookClassManagementDO.getId()));
        if (bookSchoolAssignmentDOList != null) {
            List<BookSchoolAssignmentSaveRespVO> bookSchoolAssignmentSaveRespVOList = BeanUtils.toBean(bookSchoolAssignmentDOList, BookSchoolAssignmentSaveRespVO.class);
            bookClassManagementRespVO.setBookSchoolAssignmentSaveRespVOList(bookSchoolAssignmentSaveRespVOList);
        }
        // 根据成员ID查询打卡记录
        List<BookCheckInRecordDO> bookCheckInRecordDOList = new ArrayList<>();
        bookSchoolAssignmentListVOList.forEach(item -> {
            if (Long.parseLong(bookClassManagementRespVO.getCreator()) == (item.getMemberId())) {
                item.setRole("老师");
            } else {
                item.setRole("学生");
            }
            BookCheckInRecordDO bookCheckInRecordDO = bookCheckInRecordMapper.selectOne(new QueryWrapperX<BookCheckInRecordDO>().eq("creator", item.getMemberId()));
            if (bookCheckInRecordDO != null) {
                bookCheckInRecordDOList.add(bookCheckInRecordDO);
            }
        });
        bookClassManagementRespVO.setBookSchoolAssignmentListVOList(bookSchoolAssignmentListVOList);
        if (!bookCheckInRecordDOList.isEmpty()) {
            List<AppBookCheckInRecordListVO> bookCheckInRecordListVOList = BeanUtils.toBean(bookCheckInRecordDOList, AppBookCheckInRecordListVO.class);
            bookCheckInRecordListVOList.forEach(item -> {
                List<BookDO> bookDOList = new ArrayList<>();
                String[] bookIds = item.getBookIds().split("_");
                for (String bookId : bookIds) {
                    BookDO bookDO = bookService.getBook(Long.valueOf(bookId));
                    if (bookDO != null) {
                        bookDOList.add(bookDO);
                    }
                }
                item.setBookDOList(bookDOList);
            });
            bookClassManagementRespVO.setBookCheckInRecordListVOList(bookCheckInRecordListVOList);
        }
        bookClassManagementRespVO.setNum(bookClassManagementMemberMapper
                .selectCount(new LambdaQueryWrapper<BookClassManagementMemberDO>().eq(BookClassManagementMemberDO::getClassManagementId, bookClassManagementDO.getId())));
        bookClassManagementRespVO.setCode(bookClassManagementDO.getClassManagementPassword());
        return bookClassManagementRespVO;
    }

    @Override
    public List<BookClassManagementRespVO> getClassManagementList() {
        return bookClassManagementMapper.selectJoinList(BookClassManagementRespVO.class,
                new MPJLambdaWrapper<BookClassManagementDO>()
                        .leftJoin(BookClassManagementMemberDO.class, BookClassManagementMemberDO::getClassManagementId, BookClassManagementMemberDO::getId)
                        .eq(BookClassManagementMemberDO::getMemberId, getLoginUserId()));
    }

    @Override
    public void updateBookClassManagement(BookClassManagementReqVO updateReqVO) {
        BookClassManagementDO bookClassManagementDO = BeanUtils.toBean(updateReqVO, BookClassManagementDO.class);
        bookClassManagementMapper.updateById(bookClassManagementDO);
    }

    @Override
    public BookSchoolAssignmentSaveRespVO getBookClassManagementBookSchoolAssignmentList(Long id) {
        // 查询作业详情
        BookSchoolAssignmentDO bookSchoolAssignmentDO = bookSchoolAssignmentMapper.selectOne(new QueryWrapper<BookSchoolAssignmentDO>().eq("class_management_id", id));
        BookSchoolAssignmentSaveRespVO bookSchoolAssignmentSaveRespVO = BeanUtils.toBean(bookSchoolAssignmentDO, BookSchoolAssignmentSaveRespVO.class);
        List<BookSchoolAssignmentListVO> bookSchoolAssignmentListVOList = bookClassManagementMemberMapper.selectListByClassManagementId(id);
        bookSchoolAssignmentListVOList.forEach(item -> {
            String[] bookIds = bookSchoolAssignmentDO.getBookIds().split("_");
            for (String bookId : bookIds) {
                BookClassAndSchoolDO bookClassAndSchoolDO = bookClassAndSchoolMapper.selectOne(new QueryWrapperX<BookClassAndSchoolDO>().eq("user_id", item.getMemberId())
                        .eq("book_id", bookId).eq("class_management_id", bookSchoolAssignmentDO.getClassManagementId()));
                item.setType(bookClassAndSchoolDO == null ? 1L : 0L);
            }
        });
        bookSchoolAssignmentSaveRespVO.setBookSchoolAssignmentListVOList(bookSchoolAssignmentListVOList);
        return bookSchoolAssignmentSaveRespVO;
    }

    @Override
    public Long submitJob(BookClassAndSchoolSaveReqVO bookClassAndSchoolSaveReqVO) {
        BookClassAndSchoolDO bookClassAndSchoolDO = BeanUtils.toBean(bookClassAndSchoolSaveReqVO, BookClassAndSchoolDO.class);
        bookClassAndSchoolDO.setUserId(getLoginUserId());
        bookClassAndSchoolMapper.insert(bookClassAndSchoolDO);
        return bookClassAndSchoolDO.getId();
    }

    @Override
    public Boolean deleteClass(String id) {
        bookClassManagementMapper.deleteById(id);
        return true;
    }

    @Override
    public Boolean updateClassName(String id, String className) {
        BookClassManagementDO bookClassManagementDO = new BookClassManagementDO();
        bookClassManagementDO.setId(Long.valueOf(id));
        bookClassManagementDO.setClassManagementName(className);
        bookClassManagementMapper.updateById(bookClassManagementDO);
        return true;
    }

    @Override
    public List<ClassMembersRespVO> getClassMembers(String classId) {
        List<ClassMembersRespVO> vo = new ArrayList<>();
        LambdaQueryWrapper<BookClassManagementMemberDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BookClassManagementMemberDO::getClassManagementId, classId);
        List<BookClassManagementMemberDO> bookClassManagementMemberDOS = bookClassManagementMemberMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(bookClassManagementMemberDOS)) {
            bookClassManagementMemberDOS.forEach(item -> {
                ClassMembersRespVO classMembersRespVO = new ClassMembersRespVO();
                classMembersRespVO.setMemberName(item.getMemberName());
                classMembersRespVO.setMemberId(String.valueOf(item.getMemberId()));
                classMembersRespVO.setId(String.valueOf(item.getId()));
                vo.add(classMembersRespVO);
            });
        }
        return vo;
    }

    @Override
    public Boolean deleteMemberById(String id) {
        bookClassManagementMemberMapper.deleteById(id);
        return true;
    }

}